package com.ru.application.creditscore.service;

import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
import org.springframework.transaction.annotation.Transactional;
import com.ru.application.creditscore.dao.ScoringRuleDao;
import com.ru.application.creditscore.dao.support.SearchMode;
import com.ru.application.creditscore.dao.support.SearchParameters;
import com.ru.application.creditscore.domain.ScoringFactor;
import com.ru.application.creditscore.domain.ScoringRule;
import com.ru.application.creditscore.domain.ScoringSchema;

public class ScoringRuleServiceImpl implements ScoringRuleService {
    
    private final static Logger logger = Logger.getLogger(ScoringRuleServiceImpl.class);
    private ScoringRuleDao ruleDao;
    
    public ScoringRule findRule(Integer id) {
	if (logger.isDebugEnabled()) {
		logger.debug("Find rule with Id = " + id.toString());
	}
	ScoringRule rule = new ScoringRule();
	try {
	    	rule.setId(id);
		SearchParameters sp = new SearchParameters();
		sp.searchMode(SearchMode.EQUALS);
		rule = ruleDao.findUnique(rule, sp);
	} catch (Exception e) {
		logger.error("Error: " + e.toString());
		throw new ServiceException(ServiceException.LIB_JPA_PB,
				ServiceException.CODE_JPA_PB, e);
	}
	if (logger.isDebugEnabled()) {
		logger.debug("Find rule OK with Id = " + id.toString());
	}
	return rule;
    }

    public List<ScoringRule> findAll(SearchParameters sp) {
	if (logger.isDebugEnabled()) {
		logger.debug("Find all rule");
	}
	List<ScoringRule> listRule = new ArrayList<ScoringRule>();
	ScoringRule rule = new ScoringRule();
	try {
	    listRule = ruleDao.find(rule, sp);
	} catch (Exception e) {
		logger.error("Error: " + e.toString());
		throw new ServiceException(ServiceException.LIB_JPA_PB,
				ServiceException.CODE_JPA_PB, e);
	}
	if (logger.isDebugEnabled()) {
		logger.debug("Find all rule OK");
	}
	return listRule;
    }

    public List<ScoringRule> findRuleBySchemaId(Integer schemaId, SearchParameters sp) {
	if (logger.isDebugEnabled()) {
		logger.debug("Find all rule by schemaId = " + schemaId.toString());
	}
	List<ScoringRule> listRule = new ArrayList<ScoringRule>();
	ScoringRule rule = new ScoringRule();
	try {
	    ScoringSchema schema = new ScoringSchema();
	    schema.setId(schemaId);
	    rule.setSchema(schema);
	    listRule = ruleDao.find(rule, sp);
	} catch (Exception e) {
		logger.error("Error: " + e.toString());
		throw new ServiceException(ServiceException.LIB_JPA_PB,
				ServiceException.CODE_JPA_PB, e);
	}
	if (logger.isDebugEnabled()) {
		logger.debug("Find all rule by schemaId OK");
	}
	return listRule;
    }

    public List<ScoringRule> findRuleByFactorId(Integer factorId, SearchParameters sp) {
	if (logger.isDebugEnabled()) {
		logger.debug("Find all rule by factorId = " + factorId.toString());
	}
	List<ScoringRule> listRule = new ArrayList<ScoringRule>();
	ScoringRule rule = new ScoringRule();
	try {
	    ScoringFactor factor = new ScoringFactor();
	    factor.setId(factorId);
	    rule.setFactor(factor);
	    listRule = ruleDao.find(rule, sp);
	} catch (Exception e) {
		logger.error("Error: " + e.toString());
		throw new ServiceException(ServiceException.LIB_JPA_PB,
				ServiceException.CODE_JPA_PB, e);
	}
	if (logger.isDebugEnabled()) {
		logger.debug("Find all rule by factorId OK");
	}
	return listRule;
    }

    public List<ScoringRule> findRuleBySchemaIdAndFactorId(Integer schemaId, Integer factorId, SearchParameters sp) {
	if (logger.isDebugEnabled()) {
		logger.debug("Find all rule by factorId = " + factorId.toString() + " -- schemaId = " + schemaId.toString());
	}
	List<ScoringRule> listRule = new ArrayList<ScoringRule>();
	ScoringRule rule = new ScoringRule();
	try {
	    ScoringFactor factor = new ScoringFactor();
	    factor.setId(factorId);
	    rule.setFactor(factor);
	    ScoringSchema schema = new ScoringSchema();
	    schema.setId(schemaId);
	    rule.setSchema(schema);
	    listRule = ruleDao.find(rule, sp);
	} catch (Exception e) {
		logger.error("Error: " + e.toString());
		throw new ServiceException(ServiceException.LIB_JPA_PB,
				ServiceException.CODE_JPA_PB, e);
	}
	if (logger.isDebugEnabled()) {
		logger.debug("Find all rule by factorId and schemaId OK");
	}
	return listRule;
    }
    
    @Transactional
    public boolean updateRule(ScoringRule pRule) {
	if (logger.isDebugEnabled()) {
		logger.debug("Update rule with id = " + pRule.getId().toString());
	}
	boolean result = false;
	ScoringRule rule = new ScoringRule();
	try {
	    rule = ruleDao.merge(pRule);
	} catch (Exception e) {
		logger.error("Error: " + e.toString());
		throw new ServiceException(ServiceException.LIB_JPA_PB,
				ServiceException.CODE_JPA_PB, e);
	}
	if (logger.isDebugEnabled() && rule != null) {
		logger.debug("Update rule OK");
		result = true;
	}
	return result;
    }
    
    @Transactional
    public void createRule(ScoringRule rule) {
	if (logger.isDebugEnabled()) {
		logger.debug("create rule");
	}

	try {
	    ruleDao.save(rule);
	} catch (Exception e) {
		logger.error("Error: " + e.toString());
		throw new ServiceException(ServiceException.LIB_JPA_PB,
				ServiceException.CODE_JPA_PB, e);
	}
	if (logger.isDebugEnabled()) {
		logger.debug("create rule OK");
	}
    }
    
    @Transactional
    public void removeRule(Integer id) {
	if (logger.isDebugEnabled()) {
		logger.debug("remove rule");
	}
	ScoringRule rule = new ScoringRule();
	rule.setId(id);
	try {
	    ruleDao.delete(rule);
	} catch (Exception e) {
		logger.error("Error: " + e.toString());
		throw new ServiceException(ServiceException.LIB_JPA_PB,
				ServiceException.CODE_JPA_PB, e);
	}
	if (logger.isDebugEnabled()) {
		logger.debug("remove rule OK");
	}
    }
    
    @Transactional
    public void updateListRule(List<ScoringRule> listRule) {
	if (logger.isDebugEnabled()) {
		logger.debug("updateListRule");
	}

	try {
		for (ScoringRule rule : listRule)
		    ruleDao.merge(rule);
	} catch (Exception e) {
		logger.error("Error: " + e.toString());
		throw new ServiceException(ServiceException.LIB_JPA_PB,
				ServiceException.CODE_JPA_PB, e);
	}
	if (logger.isDebugEnabled()) {
		logger.debug("updateListRule OK");
	}
    }
    
    @Transactional
    public void createListRule(List<ScoringRule> listRule) {
	if (logger.isDebugEnabled()) {
		logger.debug("rule: createListRule.");
	}

	try {
		for (ScoringRule rule : listRule)
		    ruleDao.save(rule);
	} catch (Exception e) {
		logger.error("Error: " + e.toString());
		throw new ServiceException(ServiceException.LIB_JPA_PB,
				ServiceException.CODE_JPA_PB, e);
	}
	if (logger.isDebugEnabled()) {
		logger.debug("rule: createListRule OK");
	}
    }
    
    @Transactional
    public void removeListRule(List<Integer> listId) {
	if (logger.isDebugEnabled()) {
		logger.debug("removeListRule");
	}

	try {
		for (Integer id : listId) {
		    	ScoringRule rule = new ScoringRule();
		    	rule.setId(id);
		        ruleDao.delete(rule);
		}
	} catch (Exception e) {
		logger.error("Error: " + e.toString());
		throw new ServiceException(ServiceException.LIB_JPA_PB,
				ServiceException.CODE_JPA_PB, e);
	}
	if (logger.isDebugEnabled()) {
		logger.debug("removeListRule OK");
	}
    }

    public ScoringRuleDao getRuleDao() {
        return ruleDao;
    }

    public void setRuleDao(ScoringRuleDao ruleDao) {
        this.ruleDao = ruleDao;
    }
   
}
